/*
 * ECARX Technology Limited is the owner of the copyright and the trade secret of this software.
 * Without permission, no one has the right to obtain, disclose or use this software in any way.
 */
package com.ecarx.systemui.plugin.ui.navigationbar

import android.car.hardware.CarPropertyValue
import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import com.ecarx.systemui.plugin.R
import com.ecarx.systemui.plugin.controller.hvac.HvacFanController
import com.ecarx.systemui.plugin.ui.custom.SystemBarButton
import com.ecarx.systemui.plugin.utils.AppUtils
import com.ecarx.systemui.plugin.utils.BitmapUtils
import com.ecarx.systemui.plugin.utils.LogUtils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class HvacFanSpeedView : SystemBarButton {

    private var mFanSpeed = 5
    private lateinit var fanBitmap: Bitmap
    private var paint: Paint = Paint().apply {
        color = Color.WHITE
    }
    private var fanIconRect = Rect(86, 0, 166, 85)

    private var mFanController = HvacFanController.getInstance()

    constructor(context: Context?) : this(context!!, null)
    constructor(context: Context?, attrs: AttributeSet?) : this(context!!, attrs, 0)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context!!,
        attrs,
        defStyleAttr
    )

    override fun initView() {
        super.initView()

        fanBitmap = BitmapUtils.decodeRes(context, R.drawable.ic_nav_hvac_fan)

        setOnClickListener {
            AppUtils.startClimate(context, true)
        }
    }

    private val autoOnCallback = object : CarPropertyEventCallback {
        override fun onChangeEvent(value: CarPropertyValue<*>?) {
            LogUtils.d(TAG, "autoOnCallback value:$value")
            CoroutineScope(Dispatchers.IO).launch {
                if (mFanController.isAutoOn()) {
                    mFanController.registerAutoFanSpeedCallback(autoFanSpeedCallback)
                    mFanController.unRegisterManualFanSpeedCallback(manualFanSpeedCallback)
                } else {
                    mFanController.registerManualFanSpeedCallback(manualFanSpeedCallback)
                    mFanController.unRegisterAutoFanSpeedCallback(autoFanSpeedCallback)
                }
            }
            refreshFanSpeed()
        }

        override fun onErrorEvent(p0: Int, p1: Int) {

        }
    }

    private val autoFanSpeedCallback = object : CarPropertyEventCallback {
        override fun onChangeEvent(value: CarPropertyValue<*>?) {
            CoroutineScope(Dispatchers.IO).launch {
                if (mFanController.isAutoFanSpeedAvailable()) {
                    mFanSpeed = mFanController.getAutoFanSpeed()
                    LogUtils.d(TAG, "autoFanSpeedCallback value:$value mFanSpeed:$mFanSpeed")
                } else {
                    LogUtils.w(TAG, "autoFanSpeedCallback not available")
                }
                withContext(Dispatchers.Main) {
                    invalidate()
                }
            }
        }

        override fun onErrorEvent(p0: Int, p1: Int) {

        }
    }

    private val manualFanSpeedCallback = object : CarPropertyEventCallback {
        override fun onChangeEvent(value: CarPropertyValue<*>?) {
            CoroutineScope(Dispatchers.IO).launch {
                if (mFanController.isManualFanSpeedAvailable()) {
                    mFanSpeed = mFanController.getManualFanSpeed()
                    LogUtils.d(TAG, "manualFanSpeedCallback value:$value mFanSpeed:$mFanSpeed")
                } else {
                    LogUtils.w(TAG, "manualFanSpeedCallback not available")
                }
                withContext(Dispatchers.Main) {
                    invalidate()
                }
            }
        }

        override fun onErrorEvent(p0: Int, p1: Int) {

        }
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        LogUtils.d(TAG, "onAttachedToWindow")
        refreshFanSpeed()
        CoroutineScope(Dispatchers.IO).launch {
            if (mFanController.isAutoOn()) {
                mFanController.registerAutoFanSpeedCallback(autoFanSpeedCallback)
            } else {
                mFanController.registerManualFanSpeedCallback(manualFanSpeedCallback)
            }

            mFanController.registerAutoOnCallback(autoOnCallback)
        }
    }

    private fun refreshFanSpeed() {
        CoroutineScope(Dispatchers.IO).launch {
            mFanSpeed = mFanController.getFanSpeed()
            withContext(Dispatchers.Main) {
                invalidate()
            }
        }
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        CoroutineScope(Dispatchers.IO).launch {
            mFanController.unRegisterAutoOnCallback(autoOnCallback)
            mFanController.unRegisterAutoFanSpeedCallback(autoFanSpeedCallback)
            mFanController.unRegisterManualFanSpeedCallback(manualFanSpeedCallback)
        }
    }

    override fun getContentDescriptionString(): String {
        return "HvacFanSpeedView"
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    }


    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        LogUtils.d(TAG, "onLayout: left:$left  top:$top  right:$right  bottom:$bottom")
    }


    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        canvas?.drawBitmap(fanBitmap, null, fanIconRect, paint)
        if (mFanSpeed > 0) {
            canvas?.drawText(mFanSpeed.toString(), 170f, 70f, paint.apply {
                textSize = 64f
                style = Paint.Style.FILL
            })
        }
    }

    companion object {
        private const val TAG = "HvacFanSpeedView"
    }
}